package com.repair.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.repair.entity.RepairTrack;
import com.repair.entity.RepairOrder;
import com.repair.mapper.RepairTrackMapper;
import com.repair.mapper.RepairOrderMapper;
import com.repair.service.RepairTrackService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;

@Service
public class RepairTrackServiceImpl extends ServiceImpl<RepairTrackMapper, RepairTrack> implements RepairTrackService {

    @Autowired
    private RepairTrackMapper repairTrackMapper;
    
    @Autowired
    private RepairOrderMapper repairOrderMapper;

    @Override
    @Transactional
    public void addTrack(Long orderId, Long repairmanId, Double latitude, Double longitude, Integer status) {
        RepairTrack track = new RepairTrack();
        track.setOrderId(orderId);
        track.setRepairmanId(repairmanId);
        track.setLatitude(latitude);
        track.setLongitude(longitude);
        track.setStatus(status);
        track.setCreateTime(LocalDateTime.now());
        repairTrackMapper.insert(track);
    }

    @Override
    public List<RepairTrack> getOrderTracks(Long orderId) {
        return list(new LambdaQueryWrapper<RepairTrack>()
                .eq(RepairTrack::getOrderId, orderId)
                .orderByAsc(RepairTrack::getCreateTime));
    }

    @Override
    public List<RepairTrack> getRepairmanTracks(Long repairmanId) {
        return list(new LambdaQueryWrapper<RepairTrack>()
                .eq(RepairTrack::getRepairmanId, repairmanId)
                .orderByDesc(RepairTrack::getCreateTime));
    }

    @Override
    @Transactional
    public void updateTrackStatus(Long trackId, Integer status) {
        RepairTrack track = getById(trackId);
        if (track != null) {
            track.setStatus(status);
            updateById(track);
        }
    }

    @Override
    public List<RepairTrack> getOrderTracksByStatus(Long orderId, Integer status) {
        return list(new LambdaQueryWrapper<RepairTrack>()
                .eq(RepairTrack::getOrderId, orderId)
                .eq(RepairTrack::getStatus, status)
                .orderByAsc(RepairTrack::getCreateTime));
    }

    @Override
    public Map<String, Object> getRepairmanTracksByDate(Long repairmanId, LocalDate date) {
        Map<String, Object> result = new HashMap<>();
        
        // 获取指定日期的轨迹点
        LocalDateTime startTime = date.atStartOfDay();
        LocalDateTime endTime = date.plusDays(1).atStartOfDay();
        List<RepairTrack> tracks = repairTrackMapper.findByRepairmanIdAndTimeRange(
            repairmanId, startTime, endTime);
        
        // 获取指定日期完成的订单
        List<RepairOrder> orders = repairOrderMapper.findCompletedOrdersByRepairmanAndDate(
            repairmanId, startTime, endTime);
        
        // 计算总距离和活动时长
        double totalDistance = calculateTotalDistance(tracks);
        double totalDuration = calculateTotalDuration(tracks);
        
        // 组装返回数据
        result.put("tracks", tracks);
        result.put("orders", orders);
        result.put("totalDistance", totalDistance);
        result.put("totalDuration", totalDuration);
        
        return result;
    }

    @Override
    public double calculateTotalDistance(List<RepairTrack> tracks) {
        double totalDistance = 0.0;
        if (tracks.size() < 2) {
            return totalDistance;
        }
        
        for (int i = 1; i < tracks.size(); i++) {
            RepairTrack prev = tracks.get(i - 1);
            RepairTrack curr = tracks.get(i);
            totalDistance += calculateDistance(
                prev.getLatitude(), prev.getLongitude(),
                curr.getLatitude(), curr.getLongitude()
            );
        }
        
        return totalDistance;
    }

    @Override
    public double calculateTotalDuration(List<RepairTrack> tracks) {
        if (tracks.size() < 2) {
            return 0.0;
        }
        
        LocalDateTime firstTime = tracks.get(0).getCreateTime();
        LocalDateTime lastTime = tracks.get(tracks.size() - 1).getCreateTime();
        
        return ChronoUnit.MINUTES.between(firstTime, lastTime) / 60.0;
    }

    /**
     * 计算两个坐标点之间的距离（单位：公里）
     * 使用Haversine公式计算球面两点距离
     */
    private double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
        final int R = 6371; // 地球半径（公里）
        
        double latDistance = Math.toRadians(lat2 - lat1);
        double lonDistance = Math.toRadians(lon2 - lon1);
        
        double a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2)
                + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2))
                * Math.sin(lonDistance / 2) * Math.sin(lonDistance / 2);
        
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        
        return R * c;
    }
} 